#!/usr/bin/env bash

_thisdir="$(dirname $0)"
test "${_thisdir}" = "." && _thisdir=${PWD}
_ifwroot="${_thisdir}"/qt-ifw
_arch=$(uname -m)
_date=$(date +'%Y%m%d')
_dateqif=$(date +'%Y-%m-%d')
_version=${_date}
_filename=msys2-${_arch}-${_date}.exe
_filename2=msys2-base-${_arch}-${_date}.tar.xz
_filename3=msys2-base-${_arch}-${_date}.sfx.exe
_log=/tmp/installer-${_arch}-${_date}.log
if [ "${_arch}" = "x86_64" ]; then
  _bitness=64
else
  _bitness=32
fi
_archivegen=/mingw${_bitness}/bin/archivegen.exe
_binarycreator=/mingw${_bitness}/bin/binarycreator.exe
_installerbase=/mingw${_bitness}/bin/installerbase.exe
_newmsysbase=/tmp/newmsys
_newmsys=${_newmsysbase}/msys"${_bitness}"

declare -a undo_commands

_exitcode=5

exit_with_undo() {
  for _cmd in ${undo_commands[@]}; do
    eval "${_cmd}" | tee -a ${_log}
  done
  exit ${_exitcode}
}

exit_cleanly() {
  _exitcode=$1; shift;
  local _message=$1; shift;
  echo "${_message}" | tee -a ${_log}
  exit_with_undo
}

do_seds() {
  find "${_ifwroot}" \( -name "package.xml" -or -name "config.xml" \) -exec sed -i "s|@DATE@|${_dateqif}|g" "{}" \;
  find "${_ifwroot}" \( -name "package.xml" -or -name "config.xml" \) -exec sed -i "s|@VERSION@|${_version}|g" "{}" \;
  find "${_ifwroot}" \( -name "package.xml" -or -name "config.xml" -or -name "installscript.js" \) -exec sed -i "s|@BITNESS@|${_bitness}|g" "{}" \;
  undo_commands+=("undo_seds")
}

undo_seds() {
  find "${_ifwroot}" \( -name "package.xml" -or -name "config.xml" \) -exec sed -i "s|<ReleaseDate>${_dateqif}<|<ReleaseDate>@DATE@<|g" "{}" \;
  find "${_ifwroot}" \( -name "package.xml" -or -name "config.xml" \) -exec sed -i "s|<Version>${_version}<|<Version>@VERSION@<|g" "{}" \;
  find "${_ifwroot}" \( -name "package.xml" -or -name "config.xml" -or -name "installscript.js" \) -exec sed -i "s|msys${_bitness}|msys@BITNESS@|g" "{}" \;
  find "${_ifwroot}" \( -name "package.xml" -or -name "config.xml" -or -name "installscript.js" \) -exec sed -i "s|${_bitness}bit|@BITNESS@bit|g" "{}" \;
  find "${_ifwroot}" \( -name "package.xml" -or -name "config.xml" -or -name "installscript.js" \) -exec sed -i "s|if (\"@BITNESS@bit\" === \"@BITNESS@bit\")|if (\"@BITNESS@bit\" === \"32bit\")|g" "{}" \;
}

create_archives() {
  local _data="${_ifwroot}"/packages/com.msys2.root.base/data
  [ -d "${_data}" ] && rm -rf "${_data}"
  mkdir -p "${_data}"

  local _dirs="${_newmsys}/"*
  local _compress_cmd="${_archivegen} --compression 9 ${_data}/msys${_bitness}.7z ${_dirs}"
  pushd / > /dev/null
    echo "Run: ${_compress_cmd} ..." | tee -a ${_log}
    eval "${_compress_cmd}" 2>&1 | tee -a ${_log}
    _result=$?
    if [ "${_result}" -eq "0" ]; then
          echo " archivegen succeeded. Created ${_data}/msys${_bitness}.7z" | tee -a ${_log}
    else
          exit_cleanly "3" "archivegen failed. See ${_log}"
    fi
  popd > /dev/null

  pushd ${_newmsysbase} > /dev/null
    local _compress_cmd2="/usr/bin/tar --transform='s/:/_/g' --dereference --hard-dereference -cJf ${_thisdir}/${_filename2} msys${_bitness}"
    echo "Run: ${_compress_cmd2} ..." | tee -a ${_log}
    eval "${_compress_cmd2}" 2>&1 | tee -a ${_log}
    _result=$?
    if [ "${_result}" -eq "0" ]; then
          echo " tar succeeded. Created " | tee -a ${_log}
    else
          die "MSYS2 compressing fail. See ${_log}"
    fi

    # self extracting cli 7z archive
    7z a -mx=9  "${_thisdir}/_temp.7z" "msys${_bitness}"
    cat ${_thisdir}/7zCon.sfx "${_thisdir}/_temp.7z" > "${_thisdir}/${_filename3}"
    rm "${_thisdir}/_temp.7z"
  popd > /dev/null
}

# Add -v to get more information.
make_installer() {
  eval "\"${_binarycreator}\" \
    -t \"${_installerbase}\" \
    -p \"${_ifwroot}/packages\" \
    -c \"${_ifwroot}/config/config.xml\" \
    --offline-only \
    \"${_filename}\" \
    -v"  | tee -a ${_log}
}

trap exit_with_undo 1 2 15

create_chroot_system() {
  [ -d ${_newmsysbase} ] && rm -rf ${_newmsysbase}
  mkdir -p "${_newmsys}"
  pushd "${_newmsys}" > /dev/null

    mkdir -p var/lib/pacman
    mkdir -p var/log
    mkdir -p tmp

    eval "pacman -Syu --root \"${_newmsys}\"" | tee -a ${_log}
    eval "pacman -S base --noconfirm --root \"${_newmsys}\"" | tee -a ${_log}
    _result=$?
    if [ "${_result}" -ne "0" ]; then
      exit_cleanly "1" "failed to create newmsys2 via command 'pacman -S base --noconfirm --root ${_newmsys}'"
    fi
  popd > /dev/null
}

if [ ! -f "${_archivegen}" ]; then
  eval "pacman -S --noconfirm mingw${_bitness}/mingw-w64-${_arch}-qt-installer-framework" | tee -a ${_log}
fi

if [ ! -f "${_archivegen}" ]; then
  exit_cleanly "2" "installation of qt installer framework failed. See ${_log}"
fi

if [ -f "${_log}" ]; then
  rm "${_log}"
fi

echo "Creating MSYS2 chroot system ${_newmsys}" | tee -a ${_log}
create_chroot_system

echo "Creating MSYS2 installer /tmp/${_filename}" | tee -a ${_log}
if [ -f /tmp/${_filename} ]; then
  rm -f /tmp/${_filename}
fi

do_seds
create_archives
make_installer
exit_cleanly "0" "All done, see ${_filename}"
